package com.honey.mybatis.generator.mappper;

import java.util.List;

import com.honey.compilation.xml.Document;
import com.honey.compilation.xml.XmlElement;
import com.honey.core.dbmapping.introspect.IntrospectSchema;
import com.honey.core.dbmapping.introspect.IntrospectSchemaColumn;
import com.honey.core.dbmapping.structure.Column;
import com.honey.core.dbmapping.structure.TableColumn;
import com.honey.core.types.FullyQualifiedJavaType;
import com.honey.mybatis.generator.AbstractMybatis;
import com.honey.mybatis.generator.MybatisPlugin;

public abstract class AbstractMybatisMapper  extends AbstractMybatis{
	protected IntrospectSchema introspectSchema;
	
	protected IntrospectSchemaColumn introspectSchemaColumn; 
	
	public AbstractMybatisMapper(MybatisPlugin belongPlugin){
		super(belongPlugin);
	}
	
	public AbstractMybatisMapper(MybatisPlugin belongPlugin,IntrospectSchema introspectSchema,IntrospectSchemaColumn introspectSchemaColumn) {
		super(belongPlugin);
		this.introspectSchema = introspectSchema;
		this.introspectSchemaColumn = introspectSchemaColumn;
	}

	public Document createMyBatisDocument(FullyQualifiedJavaType type , String namespace){
		
		Document document = new Document(type,MapperConstant.MYBATIS3_PUBLIC_ID,MapperConstant.MYBATIS3_SYSTEM_ID);
		document.setVersion("1.0");
		document.setEncoding("UTF-8");
		XmlElement rootElement = new XmlElement(MapperConstant.MYBATIS3_ROOT_ELEMENT);
		rootElement.addAttribute("namespace",namespace);
		document.setRootElement(rootElement);
		return document;
	}
	
	/**
	 * 主键条件
	 * @param parent
	 */
	public void addPrimaryKeyConditionElement(XmlElement parent, List<TableColumn> list , List<Column> allList){
		StringBuilder sb = new StringBuilder().append("WHERE ");
		boolean comma = false;
		String typeHandler="";
		for(TableColumn column : list ){
			if (comma)sb.append(" AND "); else comma = true;
			sb.append(column.getName()).append(" = #{")
			.append(column.getJavaProperty()).append(",jdbcType=").append(JdbcTypeName.getJdbcTypeName(column.getJdbcType()))
			.append(typeHandler)
			.append("}");
		}
		if( mybatisPlugin.isEnableVirtualDeleteKey() ){
			for(Column column : allList ){
				String value = ((TableColumn)column).getVirtualDeleteValue();
				if( column instanceof TableColumn && value !=null){
					String key = column.getName();
					String c = column.isJdbcCharacterColumn()? "'": "";
					sb.append(" AND (")
					.append( key)
					.append(" != ").append(c)
					.append(value).append(c)
					.append(" OR ")
					.append( key)
					.append(" IS NULL ")
					.append(")")
					;
				}
			}
		}
		
		parent.addTextElement(sb.toString());
	}
	
	public void addDynamicCondition(XmlElement parent,List<Column> list,String mapping){
		XmlElement ifEle = new XmlElement(parent ,"if").addAttribute("test", "_parameter != null");
		new XmlElement(ifEle,"include").addAttribute("refid", mapping);
		if( mybatisPlugin.isEnableVirtualDeleteKey() ){
			StringBuilder sb1 = new StringBuilder();
			StringBuilder sb2 = new StringBuilder();
			boolean bool =false ;
			for(Column column : list ){
				String value = ((TableColumn)column).getVirtualDeleteValue();
				if( column instanceof TableColumn && value !=null){
					String key = column.getName();
					if( bool ){
						sb2.append(" AND (" );
					}else{
						bool = true ;
					}
					String c = column.isJdbcCharacterColumn()? "'": "";
					sb1.append(" AND (")
					.append( key)
					.append(" != ").append(c)
					.append(value).append(c)
					.append(" OR ")
					.append( key)
					.append(" IS NULL ")
					.append(")")
					;
					
					sb2.append(key ).append(c)
					.append(" != ")
					.append(value).append(c)
					.append(" OR ")
					.append( key)
					.append(" IS NULL ")
					.append(")");
				}
			}
			
			if( bool ){
				ifEle.addTextElement(sb1.toString());
				XmlElement elseEle = new XmlElement(parent,"if").addAttribute("test", "_parameter == null");
				elseEle.addTextElement(" WHERE (" + sb2.toString());
			}
		}
	}
	
	/**
	 * 添加默认的动态条件
	 * @param parent
	 */
	public void addDefaultDynamicCondition(XmlElement parent,List<Column> list){
		addDynamicCondition(parent, list, "dynamic.condition.defaultDynamic");
	}
	
	/**
	 * 更新时用的动态条件
	 * @param parent
	 */
	public void addUpdateDynamicCondition(XmlElement parent ,List<Column> list){
		addDynamicCondition(parent, list, "dynamic.condition.updateDynamic");
	}
	
}
